import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
import { CommonRedisService } from './service/common.redis.service';
import AppConfig from 'config/app.config';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private readonly commonRedisService: CommonRedisService) {}

  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest();
    if (AppConfig.AuthExternal.includes(request.path) || AppConfig.ApiPathArr.includes(request.path)) {
      return true
    }
    if (AppConfig.ManagePathArr.includes(request.path) && AppConfig.AdminPathArr.includes(request.path)) {
      const token = request.headers[AppConfig.ManageHeaderKey]
      const userId = request.headers['uid']
      const token2 = request.headers[AppConfig.AdminHeaderKey]
      if (token && userId) {
        return this.commonRedisService.get(AppConfig.ManageHeaderKey + '_' + userId).then((res) => {
          return !!res && res === token;
        }).catch(() => {
          return false;
        })
      } else if (token2) {
        return this.commonRedisService.get(AppConfig.AdminHeaderKey).then((res) => {
          return !!res && res === token2;
        }).catch(() => {
          return false;
        })
      } else {
        return false
      }
    } else if (AppConfig.ManagePathArr.includes(request.path)) {
      const token = request.headers[AppConfig.ManageHeaderKey]
      const userId = request.headers['uid']
      return this.commonRedisService.get(AppConfig.ManageHeaderKey + '_' + userId).then((res) => {
        return !!res && res === token;
      }).catch(() => {
        return false;
      })
    } else if (AppConfig.AdminPathArr.includes(request.path)) {
      const token = request.headers[AppConfig.AdminHeaderKey]
      return this.commonRedisService.get(AppConfig.AdminHeaderKey).then((res) => {
        return !!res && res === token;
      }).catch(() => {
        return false;
      })
    }
  }
}
